<?php
namespace app\common\service\ConsulService;

use app\BaseService;
use SensioLabs\Consul\ServiceFactory;
use SensioLabs\Consul\Services\AgentInterface;
use app\Normal;
use SensioLabs\Consul\Services\HealthInterface;

class ConsulClientProvider extends BaseService
{
    protected $factory;
    public function __construct()
    {
        $this->factory = new ServiceFactory([
            'base_uri'  => env('CONSUL.CONSUL_URL')
        ]);
    }
    
    /**
     * Agent TCP 注册服务接口
     * @param string $serviceName
     * @param string $serviceHost
     * @param string $servicePort
     */
    public function registerAgentTcpService( string $serviceName,string $serviceHost,string $servicePort) 
    {
        $agent = $this->factory->get(AgentInterface::class);
        $server_id = $serviceHost.'_'.$servicePort;
        $app_name  = 'RpcTcpServices';
        $registerService = [
            "ID"     => $server_id,
            "Name"   => $serviceName,
            "Tags"   => ["dev"],
            "Address"=> $serviceHost,
            "Port"   => (int)$servicePort,
            "Check"  => [
                "name"      => "rpc tcp server",
                "tcp"       => $serviceHost. ":" .$servicePort ,
                "interval"  => "10s",
                "timeout"   => "30s"
            ]
        ];
        
        $response = $agent->registerService($registerService);
        if( $response->getStatusCode() == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC,"服务注册成功");
        }
        
        return Normal::returnCode(Normal::FAIL,"服务注册失败",$response->json());
    }
    
    /**
     * Agent TCP 服务接口查询
     * @param string $serviceName
     */
    public function getAgentTcpServicesList( string $serviceName)
    {
        $agent = $this->factory->get(AgentInterface::class);
        $response = $agent->services($serviceName);
        if( $response->getStatusCode() == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC,"服务查询成功",$response->json());
        }
        return Normal::returnCode(Normal::FAIL,"服务查询失败",$response->json());
    }
    
    /**
     * Agent TCP 服务接口查询
     * @param string $serviceID
     */
    public function delAgentTcpServicesByServerID( string $serviceID)
    {
        $agent = $this->factory->get(AgentInterface::class);
        $response = $agent->deregisterService($serviceID);
        if( $response->getStatusCode() == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC,"服务删除成功",$response->json());
        }
        return Normal::returnCode(Normal::FAIL,"服务删除失败",$response->json());
    }
    
    /**
     * 获取所有健康检查通过 TCP 服务接口
     * @param string $serviceName
     */
    public function getAgentHealthTcpServices( string $serviceName)
    {
        $agent = $this->factory->get(HealthInterface::class);
        $response = $agent->service($serviceName,['passing'=>true]);
        if( $response->getStatusCode() == Normal::SUC ) {
            $services = $response->json();
            $service = $services[array_rand($services)];
            return Normal::returnCode(Normal::SUC,"服务删除成功",[
                'Address'  => $service['Service']['Address'],
                'Port'    => $service['Service']['Port'],
            ]);
        }
        return Normal::returnCode(Normal::FAIL,"服务删除失败",$response->json());
    }
}